<template>
  <!-- 登录界面 -->
  <div class="login-panel">
    <div class="title drag">R-Chat</div>
    <div v-if="showLoading" class="loading-panel">
      <!-- 加载时的图片 -->
      <img src="../assets/img/loading.gif" style="height: 300px; widows: 300px;" />
    </div>
    <div class="login-form" v-else>
      <!-- 错误提示，统一显示在左上角 -->
      <div class="error-msg">{{ errorMsg }}</div>
      <el-form :model="formData" :rules="rules" ref="formDataRef" @submit.prevent>
        <!-- 输入 -->
        <el-form-item prop="email">
          <div class="email-panel">
            <!-- @focus 选中框的时候清空错误信息 -->
            <el-input :spellcheck="false" clearable placeholder="请输入邮箱" v-model.trim="formData.email" maxlength="30"
              @focus="cleanBeforeVerify">
              <template #prefix>
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-youjianzuchuangjianshenqingliucheng"></use>
                </svg>
              </template>
            </el-input>
            <!-- 下拉框展示登录过的用户的邮箱 -->
            <el-dropdown v-if="isLogin && userEmailList.length > 0" trigger="click">
              <span class="iconfont icon-xiayi"></span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item v-for="(item, index) in userEmailList" :key="index">
                    <div class="email-select" @click="selectEmail(item.email)">
                      {{ item.email }}
                    </div>
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </el-form-item>
        <!-- 某些控件只有注册的时候才显示 -->
        <el-form-item prop="nickName" v-if="!isLogin">
          <el-input :spellcheck="false" clearable placeholder="请输入用户名" v-model.trim="formData.nickName" maxlength="12"
            @focus="cleanBeforeVerify">
            <template #prefix>
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-youjian1"></use>
              </svg>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input show-password clearable placeholder="请输入密码" v-model.trim="formData.password"
            @focus="cleanBeforeVerify">
            <template #prefix>
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-Lock"></use>
              </svg>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="rePassword" v-if="!isLogin">
          <el-input show-password clearable placeholder="请再次输入密码" v-model.trim="formData.rePassword"
            @focus="cleanBeforeVerify">
            <template #prefix>
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-Lock"></use>
              </svg>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="checkCode">
          <el-input :spellcheck="false" placeholder="请输入验证码" v-model.trim="formData.checkCode"
            @focus="cleanBeforeVerify" @keydown.enter="submit">
            <template #prefix>
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-Enable"></use>
              </svg>
            </template>
            <template #suffix>
              <!-- 验证码图片 -->
              <img :src="checkCodeUrl" class="check-code" @click="getCheckCode" />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item>
          <el-button class="login-btn" type="primary" @click="submit">{{
            isLogin ? '登录' : '注册'
          }}</el-button>
        </el-form-item>
        <div class="bottom-link" @click="changeOpType">
          <span class="a-link">{{ isLogin ? '没有' : '已有' }}账号？</span>
        </div>
      </el-form>
    </div>
  </div>
  <!-- 窗口操作按钮 -->
  <WinOp :showSetTop="false" :showMin="false" :showMax="false" :closeType="0"></WinOp>
</template>

<script setup>
import { ref, reactive, getCurrentInstance, nextTick, onMounted } from 'vue'
import md5 from 'js-md5';

import { useRouter } from 'vue-router';
const router = useRouter()

import { useUserInfoStore } from '../stores/UserInfoStore';
const UserInfoStore = useUserInfoStore()

const { proxy } = getCurrentInstance()

const formData = ref({})
const formDataRef = ref()
const rules = {}

const isLogin = ref(true)
const changeOpType = () => {
  isLogin.value = !isLogin.value
  /* 使用preload里自定义api向主进程发送消息修改窗体大小 */
  myApi.loginOrRegisterSwitch(isLogin.value)
  /* 控件变化，清空填写的数据，重新获取验证码 */
  nextTick(() => {
    formDataRef.value.resetFields()
    formData.value = {}
    cleanBeforeVerify()
    getCheckCode()
  })
}

/* 获取验证码 */
const checkCodeUrl = ref(null)
const getCheckCode = async () => {
  let result = await proxy.Request({
    method: 'get',
    url: proxy.Api.checkCode
  })
  if (!result) {
    return
  }
  checkCodeUrl.value = result.data.checkCode
  // 存储验证码key，用于提交时验证
  localStorage.setItem('checkCodeKey', result.data.checkCodeKey)
}
// 开始时就要获取验证码
getCheckCode()

/* 统一在最上面的地方报错 */
const errorMsg = ref(null)

const showLoading = ref(false)

const submit = async () => {
  // 验证信息
  cleanBeforeVerify()
  if (!verifyBeforeSubmit('checkEmail', formData.value.email)) {
    errorMsg.value = '请输入正确格式的邮箱'
    return
  }
  if (!isLogin.value && !verifyBeforeSubmit('checkNickName', formData.value.nickName)) {
    errorMsg.value = '请输入6-12位的用户名'
    return
  }
  if (!verifyBeforeSubmit('checkPassword', formData.value.password)) {
    errorMsg.value = '请输入8位以上至少包含字母、数字或特殊字符其中两种的密码'
    return
  }
  if (!isLogin.value && !(formData.value.rePassword == formData.value.password)) {
    errorMsg.value = '请确认输入了一致的密码'
    return
  }
  if (!verifyBeforeSubmit('checkCheckCode', formData.value.checkCode)) {
    errorMsg.value = '请输入验证码'
    return
  }
  // 发送请求的时候显示加载
  showLoading.value = true
  // 发送请求
  let result = await proxy.Request({
    url: isLogin.value ? proxy.Api.login : proxy.Api.register,
    showError: false,
    showLoading: isLogin.value ? false : true, // 登陆的时候不显示loading
    method: 'post',
    params: {
      email: formData.value.email,
      nickName: formData.value.nickName,
      password: isLogin.value ? md5(formData.value.password) : formData.value.password, // 登录传密文，注册传明文
      checkCodeKey: localStorage.getItem('checkCodeKey'),
      checkCode: formData.value.checkCode
    },
    errorCallback: (response) => {
      showLoading.value = false
      getCheckCode()
      proxy.Message.error(response.info)
    }
  })
  // 发送完毕关闭加载页面
  showLoading.value = false
  if (!result) {
    return;
  }
  if (isLogin.value) {
    // 用pinia记录登录信息
    UserInfoStore.setUserInfo(result.data)
    localStorage.setItem('token', result.data.token)

    // 获取屏幕大小
    const screenWidth = window.screen.width
    const screenHeight = window.screen.height

    // 和主进程交互，需要把ws放进主进程里（放渲染进程里失去焦点后可能心跳会断开）
    await myApi.openChat({
      email: formData.value.email,
      nickName: result.data.nickName,
      token: result.data.token,
      userId: result.data.userId,
      admin: result.data.admin,
      screenWidth: screenWidth,
      screenHeight: screenHeight
    })

    // 进入主界面
    router.push('/main')
  }
  else {
    // 注册成功直接跳转到登陆界面即可
    proxy.Message.success('注册成功')
    changeOpType()
  }
}

const cleanBeforeVerify = () => {
  errorMsg.value = null
}

const verifyBeforeSubmit = (type, value) => {
  if (proxy.Utils.isEmpty(value)) return false
  return proxy.Verify[type](value)
}

const userEmailList = ref([])

const selectEmail = (email) => {
  formData.value.email = email
}

/* 初始化登录界面时将后端路径和ws连接路径传递给主进程 */
const init = async () => {
  myApi.setLocalStore({ key: 'prodDomain', value: proxy.Api.prodDomain })
  myApi.setLocalStore({ key: 'devDomain', value: proxy.Api.devDomain })
  myApi.setLocalStore({ key: 'prodWsDomain', value: proxy.Api.prodWsDomain })
  myApi.setLocalStore({ key: 'devWsDomain', value: proxy.Api.devWsDomain })

  // 获取本地数据库中所有登陆过的邮箱信息（下拉框选择用户账号登录）
  userEmailList.value = await myApi.getUserEmailList()
  // console.log(userEmailList.value.length > 0, isLogin.value)
}

onMounted(async () => {
  await init()
})
</script>

<style lang="scss" scoped>
.email-select {
  width: 380px;
}

.icon {
  width: 1.5em;
  height: 1.5em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}

.loading-panel {
  text-align: center;
  background-color: #ddd;
}

.login-panel {
  background: #fff;
  border-radius: 3px;
  border: 1px solid #ddd;

  .title {
    height: 30px;
    padding: 5px 0px 0px 10px;
    font-size: 18px;
    font-weight: 800;
  }

  .login-form {
    padding: 0px 15px 29px 15px;

    :deep(.el-input__wrapper) {
      box-shadow: none;
      border-radius: none;
    }

    .el-form-item {
      border-bottom: 1px solid #ddd;
    }

    .email-panel {
      align-items: center;
      width: 100%;
      display: flex;

      .input {
        flex: 1;
      }

      .icon-xiayi {
        cursor: pointer;
        margin-left: 3px;
        width: 16px;
        border: none;
      }
    }

    .error-msg {
      line-height: 30px;
      height: 30px;
      color: #fb7373;
    }

    .check-code-panel {
      display: flex;

      .check-code {
        cursor: pointer;
        width: 120px;
        margin-right: auto;
      }
    }

    .login-btn {
      margin-top: 20px;
      width: 100%;
      height: 36px;
      font-size: 16px;
    }

    .bottom-link {
      text-align: right;
    }
  }
}
</style>
